﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace DirectX_CS
{
public class AnimatedCartesian3dSurface	: Cartesian3dSurface, IAnimated, IRangeModifiable
{
	[PGBrowsable]
	public const int frames_per_change = 1;
	[PGBrowsable]
	public Cartesian3dSurface Surface
	{
		get { return (Cartesian3dSurface) this; }
	}

	private double mDT = .01;
	[PGBrowsable]
	public double DTime
	{
		get { return mDT; }
		set { mDT = value; }
	}
	private double framesSinceLastDataChange = 0;

	//Animated3dSurface(Device device, ManagedRenderer rendManager, DataCreator data)
	public AnimatedCartesian3dSurface(Device device, PrimitiveManager rendManager)
		:base(device, rendManager)
    {
		//mXMin = xmin; mXMax = xmax; mYMin = ymin; mYMax = ymax; 
		//mDivisionsX = divisionsX; mDivisionsY = divisionsY;

		dataCreator = new CartesianDataCreator(ZFuncSinCosAndTime,
			dataCreator.XMin, dataCreator.XMax, 
			dataCreator.YMin, dataCreator.YMax, 
			dataCreator.DivisionsX, dataCreator.DivisionsY);
		Recreate();

		PrimitiveManager.Register(this);
    }

	//void SetData()
    //{
    //    mDataCreator = new DataCreator(mZFunc, 0, 200, 0, 200, 50, 50);

    //    mDataCreator.CreateVertexData();
    //    if (this != null)
    //        this.DataCreator = mDataCreator;
    //}
	protected bool mDoPreRender = true;
	[PGBrowsable]
	public bool PreRenderEnabled
	{
		get { return mDoPreRender; }
		set { mDoPreRender = value; }
	}
	protected bool mDoPostRender = true;
	[PGBrowsable]
	public bool PostRenderEnabled
	{
		get { return mDoPostRender; }
		set { mDoPostRender = value; }
	}
	public void PreRender()
    {
        bool recreateData = DoMotion();
        if (recreateData)
        {
			Recreate();
        }
    }
	public void PostRender()
	{

	}
    private bool DoMotion()
    {
        bool recreateData = false;

		double time = Time;
        if (framesSinceLastDataChange == frames_per_change)
        {
            //mWavePosition2d.X += (float)mDT * distancePerGeneration;

			time += mDT;

			if (time == double.MaxValue - mDT)
			{
				ResetAnimated();
			}

            //important:
            framesSinceLastDataChange = 0;

            recreateData = true;
        }
        else
        {
        }
        framesSinceLastDataChange++;
		Time = time;
        return recreateData;
    }
	public void ResetAnimated()
	{
		Time = 0;
		framesSinceLastDataChange = 0;
	}

	[PGBrowsable]
    public float mCoeffSinInSinCos = 3;
    public float ZFuncSinCosAndTime(float mTime, float x, float y)
    {
        return 1 + CartesianDataCreator.xyZFuncSinCos(x,y) + mCoeffSinInSinCos * sinf(x + mTime);// +mCoeffCos * cosf(y + mTime);
    }
    /*
    float CoolZFunc2(float x, float y)
    {
        return 1 + DataCreator.xyZFuncSinCos(x,y) + WaveHeight(x,y,mTime);// +mCoeffCos * cosf(y + mTime);
    } 
    float h = 4;
    float maxWaveLengthEffect = (float)Math.PI;
    float distancePerGeneration = .1f;

    float WaveHeight(float x, float y, double t)
    {

        Vector2 dist =  new Vector2(x,y) - mWavePosition2d;
        float length = dist.Length();
        float heightComponent = cosf(length);
      
        if (length <= maxWaveLengthEffect)
        {
            return h + h*heightComponent;
        }
        else
        {
            return 0;
        }
    }
    */

    private static float cosf(double d)
    {
        return (float)Math.Cos(d);
    }
    private static float sinf(double d)
    {
        return (float)Math.Sin(d);
    }
}
}
